package com.yichuang.security.javajwt.main.config;


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * <p> </p>
 *
 * @author tuonioooo
 * @site https://miliqkdoc.motopa.cn/
 * @date 2018/8/22 14:20
 */
@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {


    /**
     * 没有配置passwordEncoder会抛java.lang.IllegalArgumentException:  There is no PasswordEncoder mapped for the id "null"
     * passwordEncoder 方案一  明文存储，用于测试，不能用于生产
     * PasswordEncoder passwordEncoder(){
     * return NoOpPasswordEncoder.getInstance();
     * }
     * password 方案二：用 BCrypt 对密码编码
     * PasswordEncoder passwordEncoder(){
     * return new BCryptPasswordEncoder();
     * }
     * password 方案三：支持多种编码，通过密码的前缀区分编码方式,推荐
     * PasswordEncoder passwordEncoder(){
     * return PasswordEncoderFactories.createDelegatingPasswordEncoder();
     * }
     *
     * @return
     * @see
     * [
     * https://docs.spring.io/spring-security/reference/5.7/servlet/authentication/passwords/password-encoder.html
     * https://docs.spring.io/spring-security/site/docs/5.0.4.RELEASE/reference/htmlsingle/#10.3.2 DelegatingPasswordEncoder
     * ]
     * 为了解决：Encoded password does not look like BCrypt这个问题， 防止获取token，401错误 采用如下方式
     * 参考文档：docs/authentication/password-storage/in-memory-code.md
     * 为了测试创建的空密码，生成环境不能这么使用
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }

    /**
     * 必须手动配置认证凭证管理器，为了在 AuthorizationServerConfiguration 引用
     *
     * @return
     * @throws Exception
     * @see [docs/oauth2/core.md]
     */
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

}
